package b4.net
{
	import b4.model.player.*;
	import b4.util.basic.*;
	import b4.util.json.*;
	import b4.util.profile.*;
	
	import flash.events.*;
	import flash.net.*;
	
	public class ServerRequest extends EventDispatcher
	{
		//动作
		public var action:String;
		//参数
		public var params:Object;
		//对话号
		public var sessionId:String;
		//呼叫号
		public var callId:int;
		//用户id
		public var myId:int;
		//上次呼叫号（互斥）
		private static var lastCallId:int;
		//请求URL
		private var postUrl:String;
		//同步时的服务器时间(单位：秒）
		private static var serverTime:int;
		//同步时的客户端时间（单位：秒）
		private static var clientTime:int;
		//时限（秒）
		private const processTimeOut:int = 10;
		//正在处理标志（互斥）
		private static var processingFlag:Boolean;	
		
		public function ServerRequest(action:String, params:Object = null)
		{
			this.action = action;
			this.params = params;
			this.postUrl = GameProfile.URL_Action;
		}
		
		public function post(force:Boolean = false):Boolean
		{
			var currentSeconds:int = BTime.currentSeconds(); 
			if (!force && processingFlag && currentSeconds - lastCallId < processTimeOut)
				return false;
			//准备参数
			var variables:URLVariables = new URLVariables();
			var pm:PlayerManager = PlayerManager.getInstance();
			if (pm.me != null)
			{
				this.myId = pm.me.id;
				this.sessionId = pm.me.sessionId;
				this.callId = currentSeconds > lastCallId ? currentSeconds : lastCallId + 1;
			}
			var dataString:String = JSON.encode(this);
			dataString = utf8Encode(dataString);
			variables.json = escape(dataString);
			variables.b2Sig = generateSig(variables, GameProfile.SERVER_SECRET);
			//发送请求
			var request:URLRequest = new URLRequest(postUrl);
			request.method = URLRequestMethod.POST;
			request.data = variables;
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(Event.COMPLETE, onURLLoadComplete);
			loader.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
			try
			{
				processingFlag = true;
				lastCallId = callId;
				loader.load(request);
			}
			catch (error:Error)
			{
				processingFlag = false;
			}
			return processingFlag;
		}
		
		private function handleIOError(event:IOErrorEvent):void
		{
			processingFlag = false;
		}
		 
		//对中文进行UTF编码转化
		private function utf8Encode(string:String):String 
		{
			string = string.replace(/\r\n/g,'\n');
			string = string.replace(/\r/g,'\n');
			
			var utfString:String = "";
			
			for (var i:int = 0 ; i < string.length ; i++) 
			{
				var chr:Number = string.charCodeAt(i);
				if (chr < 128) 
				{
					utfString += String.fromCharCode(chr);
				}
				else if ((chr > 127) && (chr < 2048)) 
				{
					utfString += String.fromCharCode((chr >> 6) | 192);
					utfString += String.fromCharCode((chr & 63) | 128);
				}
				else 
				{
					utfString += String.fromCharCode((chr >> 12) | 224);
					utfString += String.fromCharCode(((chr >> 6) & 63) | 128);
					utfString += String.fromCharCode((chr & 63) | 128);
				}
			}
			return utfString;
		}
		
		//生成指纹
		private function generateSig(variables:URLVariables, secret:String):String
		{
			var varArray:Array = new Array();
			for (var key:String in variables)
			{
				varArray.push(key + "=" + variables[key]);
			} 
			varArray.sort();
			var varStr:String = varArray.join("");
			varStr += secret;
			varStr = utf8Encode(varStr);
			return Md5.hash(varStr);
		}
		
		private function onURLLoadComplete(event:Event):void
		{
			var data:String = event.target.data;
			data = data.substr(data.indexOf("{"));
			processingFlag = false;
			var jsonObj:Object = JSON.decode(data, false);
			BTime.setServerTime(jsonObj.timeStamp);
			var serverEvent:ServerEvent = new ServerEvent(jsonObj.action);
			serverEvent.jsonObj = jsonObj;
			dispatchEvent(serverEvent);
		}
		
		public function setPostUrl(postUrl:String):void
		{
			this.postUrl = postUrl;
		}
		
	}
}